﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zxb.DayWork.Logic;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Xml;
using Zxb.DayWork.Core;
using System.Reflection;
using System.IO;


namespace Zxb.DayWork.Test
{
    public class ReflectionTest
    {
        //static void Main(string[] args)
        //{
        //    ////楼盘基本信息导入 增量
        //    //BatchLoopWorkerTest.RunTest();

        //    //BatchWorkerTest.RunTest();

        //    Test();

        //    //HomeWorkUpdateHitsWorker.GetObjectTest();
        //    //HomeWorkUpdateHitsWorker.UpCaseHitTest();
        //    //HomeWorkUpdateHitsWorker.UpCompanyNewsTest();

        //    //OneTimeWorkTest.DianpuUrlTest();

        //    Console.ReadLine();
        //}

        public static void Test()
        {
            //FileRelectionNoParamTest();
            //FileReflectionWithParamTest();
            //ReflectFromConfigFile();
            //ConstructorTest();
            //EnumTest();
            //ConstructorWithEnumTest();
            //ConstructorWithDateTimeTest();
            //ReflectFromConfigFile();
            ReflectionAssistant.ReflectFromConfigFile();

            //Type tp = Type.GetType("Zxb.DayWork.Logic.BatchWorker");




            //tp tpins = new TestClassA();
            // reading specific custom section in custom group--------------
            //NameValueCollection serverSection = (NameValueCollection)ConfigurationManager.GetSection("Workers");
            //if (serverSection != null)
            //{
            //    foreach (string key in serverSection)
            //    {
            //        Console.WriteLine("Section Key: {0}, {1}", key, serverSection[key]);
            //    }
            //}

            //ConfigurationManager.AppSettings["Worker"].
            //System.Configuration.Configuration configBB = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            //ConfigurationSectionGroup serversGroup = configBB.SectionGroups.Get("Workers");

            //Console.WriteLine("Key value: {0}", serversGroup.Sections.Count.ToString());

            //for (int cnt = 0; cnt < serversGroup.Sections.Count; cnt++)
            //{
            //    ConfigurationSection csTmp = serversGroup.Sections[cnt];
            //    serverSection = (NameValueCollection)ConfigurationManager.GetSection("Servers/" + csTmp.SectionInformation.Name);
            //    if (serverSection != null)
            //    {
            //        foreach (string key in serverSection)
            //        {
            //            Console.WriteLine("Section Key: Servers/{0} {1}, {2}", csTmp.SectionInformation.Name, key, serverSection[key]);
            //        }
            //    }
            //}

        }

        public static void FileRelectionNoParamTest()
        {
            IRun inst = GetInstance("Zxb.DayWork.Logic", "Zxb.DayWork.Logic.CityIDWorker");
            inst.Run();
        }

        public static void FileReflectionWithParamTest()
        {
            //IRun inst = GetInstance("Zxb.DayWork.Logic", "Zxb.DayWork.Logic.CityIDWorker", null);
            IRun inst = GetInstance("Zxb.DayWork.Logic", "Zxb.DayWork.Logic.RealEstateWorker", new object[] { NorthSouth.North, 10000 });
            inst.Run();
        }

        public static void ConstructorTest()
        {
            Type t = GetType("Zxb.DayWork.Logic", "Zxb.DayWork.Logic.RealEstateWorker");
            ConstructorInfo[] ci = t.GetConstructors();    //获取类的所有构造函数
            foreach (ConstructorInfo c in ci) //遍历每一个构造函数
            {
                ParameterInfo[] ps = c.GetParameters();    //取出每个构造函数的所有参数
                foreach (ParameterInfo pi in ps)   //遍历并打印所该构造函数的所有参数
                {
                    Console.Write(pi.ParameterType.ToString() + " " + pi.Name + ",");
                }
                Console.WriteLine();
            }
        }

        public static void EnumTest()
        {
            string enumtype = "Zxb.DayWork.Logic.NorthSouth";
            string dllname = "Zxb.DayWork.Logic";
            string initvalue = "North";
            Type t = GetType(dllname, enumtype);
            Console.WriteLine(t.FullName);
            object o= Enum.Parse(t, initvalue);
            Console.WriteLine(((NorthSouth)o).GetType());
            Console.WriteLine((NorthSouth)o);
            //RealEstateWorker worker = new RealEstateWorker(o, 10000);
            //RealEstateWorker worker = new RealEstateWorker((t)o, 10000);
        }

        public static void ConstructorWithEnumTest()
        {
            string enumtype = "Zxb.DayWork.Logic.NorthSouth";
            string dllname = "Zxb.DayWork.Logic";
            string initvalue = "North";

            Type t = GetType("Zxb.DayWork.Logic", "Zxb.DayWork.Logic.RealEstateWorker");
            Type[] pt = new Type[2];
            pt[0] = GetType(dllname, enumtype);
            pt[1] = Type.GetType("System.Int32");
            //pt[1] = GetType("System","System.Int32");
            ConstructorInfo ci = t.GetConstructor(pt);
            //构造Object数组，作为构造函数的输入参数 
            object[] obj = new object[2];
            obj[0] = GetParam(pt[0], initvalue);
            obj[1] = GetParam(pt[1], "10000");
            //调用构造函数生成对象 
            object o = ci.Invoke(obj);
            //调用生成的对象的方法测试是否对象生成成功 
            //((RealEstateWorker)o).Run();
            ((IRun)o).Run();

            //ConstructorInfo[] ci = t.GetConstructors();    //获取类的所有构造函数
            //foreach (ConstructorInfo c in ci) //遍历每一个构造函数
            //{
            //    ParameterInfo[] ps = c.GetParameters();    //取出每个构造函数的所有参数
            //    foreach (ParameterInfo pi in ps)   //遍历并打印所该构造函数的所有参数
            //    {
            //        Console.Write(pi.ParameterType.ToString() + " " + pi.Name + ",");
            //    }
            //    Console.WriteLine();
            //}
        }

        public static void ConstructorWithDateTimeTest()
        {
            Type t = GetType("Zxb.DayWork.Logic", "Zxb.DayWork.Logic.ClickWorker");

            Type[] ptypes = new Type[2];
            ptypes[0] = Type.GetType("System.DateTime");
            ptypes[1] = Type.GetType("System.DateTime");

            //构造Object数组，作为构造函数的输入参数 
            object[] objs = new object[2];
            objs[0] = GetParam(ptypes[0], "2012-03-25");
            objs[1] = GetParam(ptypes[1], "2012-03-27");

            //ConstructIRun(t, ptypes, objs);
            ReflectionAssistant.ConstructIRun(t, ptypes, objs);
            ////调用构造函数生成对象 
            //ConstructorInfo ci = t.GetConstructor(ptypes);
            //object o = ci.Invoke(objs);

            ////调用生成的对象的方法测试是否对象生成成功 
            ////((ClickWorker)o).Run();
            //((IRun)o).Run();
        }
        //public static void ConstructIRun(Type t, Type[] ptypes, object[] objs)
        //{
        //    ConstructorInfo ci = t.GetConstructor(ptypes);
        //    object o = ci.Invoke(objs);
        //    ((IRun)o).Run();
        //}

        //public static Dictionary<string, Assembly> dic_Key_Asm = new Dictionary<string, Assembly>();
        //public static Type FindType(string ptype)
        //{
        //    Type tt = null;
        //    tt = Type.GetType(ptype);
        //    if (tt != null)
        //    {
        //        return tt;
        //    }
        //    foreach (Assembly asm in dic_Key_Asm.Values)
        //    {
        //        tt = asm.GetType(ptype, false, true);
        //        if (tt != null)
        //        {
        //            break;
        //        }
        //    }
        //    return tt;
        //}

        //public static void ReflectFromConfigFile()
        //{
        //    string path = string.Concat(AppDomain.CurrentDomain.BaseDirectory, "dll");
        //    string[] fileEntries = Directory.GetFiles(path);
        //    foreach (string fileentry in fileEntries)
        //    {
        //        Assembly asm = Assembly.LoadFile(fileentry);
        //        dic_Key_Asm[fileentry] = asm;
        //    }
        //    //DirectoryInfo fdir = new DirectoryInfo(path);
        //    //FileInfo[] file = fdir.GetFiles(); 


        //    XmlDocument xmldoc = new XmlDocument();
        //    xmldoc.Load("DayWorkClass.config");

        //    XmlNodeList list = xmldoc.SelectNodes("configuration/components/component");
        //    foreach (XmlNode node in list)
        //    {
        //        string typeinfo = node.Attributes["type"].Value;
        //        ////先判断typeName格式是否正确
        //        //string[] ss = typeinfo.Split(',');
        //        //if (ss.Length < 2)
        //        //{
        //        //    Logger.InfoLog.ErrorFormat("{0}不是正确的格式，应为NameSpace.TypeName,FileName.dll", typeinfo);
        //        //    continue;
        //        //}
        //        //string classFullName = ss[0];
        //        //string dllRelativeName = ss[1];
        //        //Type t = GetType(dllRelativeName, classFullName);
        //        Type t = FindType(typeinfo);
        //        //Console.WriteLine(t.FullName);

        //        ArrayList types = new ArrayList();
        //        ArrayList plist = new ArrayList();
        //        XmlNodeList paramList = node.SelectNodes("param");
        //        foreach (XmlNode pnode in paramList)
        //        {
        //            string ptype = pnode.Attributes["type"].Value;
        //            string pvalue = pnode.Attributes["value"].Value;
        //            //string pcategory = pnode.Attributes["category"].Value;


        //            Type pt = FindType(ptype);
        //            //Type pt = Type.GetType(ptype);
        //            object p = GetParam(pt, pvalue);
        //            types.Add(pt);
        //            plist.Add(p);
        //            //if (pcategory == "custom")
        //            //{
        //            //    Type pt = Type.GetType(ptype);
        //            //    object p = GetParam(pt, pvalue);
        //            //    types.Add(pt);
        //            //    plist.Add(p);
        //            //}
        //            //if (pcategory == "system")
        //            //{
        //            //    Type pt = Type.GetType(ptype);
        //            //    object p = GetParam(pt, pvalue);
        //            //    types.Add(pt);
        //            //    plist.Add(p);
        //            //}
        //        }

        //        ConstructIRun(t, types.ToArray().Cast<Type>().ToArray(), plist.ToArray());
        //    }
        //}


        //public static void ReflectFromConfigFile()
        //{
        //    XmlDocument xmldoc = new XmlDocument();
        //    xmldoc.Load("DayWorkClass.config");

        //    XmlNodeList list = xmldoc.SelectNodes("configuration/components/component");
        //    foreach (XmlNode node in list)
        //    {
        //        string typeinfo = node.Attributes["type"].Value;
        //        //先判断typeName格式是否正确
        //        string[] ss = typeinfo.Split(',');
        //        if (ss.Length < 2)
        //        {
        //            Logger.InfoLog.ErrorFormat("{0}不是正确的格式，应为NameSpace.TypeName,FileName.dll", typeinfo);
        //            continue;
        //        }
        //        string classFullName = ss[0];
        //        string dllRelativeName = ss[1];

        //        IRun inst = GetInstance(dllRelativeName, classFullName);
        //        inst.Run();
        //    }
        //}

        public static IRun GetInstance(string dllName,string classFullName)
        {
            string dllFullPath = string.Format("{0}{1}.dll", AppDomain.CurrentDomain.BaseDirectory, dllName);
            Assembly asm = Assembly.LoadFile(dllFullPath);
            IRun myInstance = (IRun)asm.CreateInstance(classFullName);
            return myInstance;
        }

        public static IRun GetInstance(string dllName, string classFullName, params object[] args)
        {
            string dllFullPath = string.Format("{0}{1}.dll", AppDomain.CurrentDomain.BaseDirectory, dllName);
            Assembly asm = Assembly.LoadFile(dllFullPath);
            IRun myInstance = (IRun)asm.CreateInstance(classFullName, true, BindingFlags.CreateInstance, null, args, null, null);
            return myInstance;
        }

        public static Type GetType(string dllName, string classFullName)
        {
            string dllFullPath = string.Format("{0}{1}.dll", AppDomain.CurrentDomain.BaseDirectory, dllName);
            Assembly asm = Assembly.LoadFile(dllFullPath);
            Type tp = asm.GetType(classFullName);
            return tp;
        }

        //public static Type GetType(string category, string dllName, string classFullName)
        //{
        //    if (category == "base")
        //    {

        //    }
        //    string dllFullPath = string.Format("{0}{1}.dll", AppDomain.CurrentDomain.BaseDirectory, dllName);
        //    Assembly asm = Assembly.LoadFile(dllFullPath);
        //    Type tp = asm.GetType(classFullName);
        //    return tp;
        //}

        public static object GetParam(Type t, string value)
        {
            object result = null;
            if (t.IsEnum)
            {
                result= Enum.Parse(t, value);
                return result;
            }
            result = Convert.ChangeType(value, t);
            return result;
        }

        //public static IRun GetReserveInstance(string typeName)
        //{
        //    //先判断typeName格式是否正确
        //    string[] ss = typeName.Split(',');
        //    if (ss.Length < 2)
        //    {
        //        log4net.LogManager.GetLogger("loginfo").ErrorFormat("{0}不是正确的格式，应为NameSpace.TypeName,FileName.dll", typeName);
        //        return null;
        //    }
        //    string classFullName = ss[0];
        //    string dllRelativeName = ss[1];
        //    //缓存依赖于文件，文件变化则清除缓存，重新反射加载实例
        //    CacheManager cacheManager = CacheFactory.GetCacheManager();
        //    IRun reserveInstance = cacheManager.GetData(classFullName) as IRun;
        //    if (reserveInstance == null)
        //    {
        //        try
        //        {
        //            string dllFullPath = string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, dllRelativeName);
        //            byte[] buf = System.IO.File.ReadAllBytes(dllFullPath);
        //            Assembly asm = Assembly.Load(buf);
        //            reserveInstance = (IRun)asm.CreateInstance(classFullName);
        //            FileDependency fileDep = new FileDependency(dllFullPath);
        //            cacheManager.Add(classFullName, reserveInstance, CacheItemPriority.Normal, null, fileDep);
        //        }
        //        catch (Exception ex)
        //        {
        //            Console.WriteLine("反射创建实例时错误：" + ex.Message);
        //            log4net.LogManager.GetLogger("loginfo").Error("反射创建实例时错误：" + ex.Message);
        //        }
        //    }
        //    return reserveInstance;
        //}
    }

    public class TestClassA : BatchWorker
    {
        protected override void ReadData()
        {
            //throw new NotImplementedException();
        }
        protected override void ProcessData()
        {
            //throw new NotImplementedException();
        }
        protected override void WriteData()
        {
            Console.WriteLine("write");
            //throw new NotImplementedException();
        }
    }
}
